package jmine.tec.web.wicket.component.menu;

import static jmine.tec.web.wicket.component.menu.MenuPanel.SEPARATOR;

import images.ImageResources;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import jmine.tec.web.wicket.component.AutoHideMarkupContainer;

import org.apache.wicket.ResourceReference;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.Image;

/**
 * @author katsuo.ogawa
 * @date Jul 5, 2011
 */
public class MenuItem implements Serializable {

    private final String label;

    private final MenuItemPanel menuItemPanel;

    private final List<MenuLink> links = new ArrayList<MenuLink>();

    private final Map<String, MenuItem> subMenuItems = new LinkedHashMap<String, MenuItem>();

    private final StringBuilder path = new StringBuilder();

    /**
     * Construtor.
     * 
     * @param label Label
     */
    public MenuItem(String label) {
        this.label = label;
        AutoHideMarkupContainer menuContainer = new AutoHideMarkupContainer("menuContainer");
        menuContainer.setMarkupId(label);
        menuContainer.setOutputMarkupId(true);
        menuContainer.add(new Label("menuLabel", label));
        menuContainer.add(new Image("setaMenu", new ResourceReference(ImageResources.class, "seta_menu.png")).setVisible(false));

        menuContainer.add(new ListLink("links", this.links));  

        this.path.append(label);
        this.menuItemPanel = new MenuItemPanel(label, menuContainer);
    }

    /**
     * @see MenuPanel#build()
     */
    public void build() {
        List<MenuItem> itens = new ArrayList<MenuItem>();
        for (MenuItem menuItem : this.getChildren()) {
            menuItem.build();
            itens.add(menuItem);
        }
        this.menuItemPanel.getMenuContainer().add(new MenuBar("subMenubarLinks", itens));
    }

    /**
     * @return the menuContainer
     */
    public MenuItemPanel getMenuItemPanel() {
        return this.menuItemPanel;
    }

    /**
     * Adiciona um submenu a este menu.
     * 
     * @param subMenuItem {@link MenuItem}
     */
    public void addSubMenu(MenuItem subMenuItem) {
        this.subMenuItems.put(subMenuItem.getLabel(), subMenuItem);
        subMenuItem.setPath(this.path.toString());
        subMenuItem.getMenuItemPanel().getMenuContainer().get("setaMenu").setVisible(true);
    }

    /**
     * @param parentPath Parent Path
     */
    public void setPath(String parentPath) {
        this.path.insert(0, parentPath + MenuPanel.SEPARATOR);
    }

    /**
     * Adiciona um link ao submenu.
     * 
     * @param link {@link MenuLink}
     */
    public void addLink(MenuLink link) {
        link.setPath(this.path.toString());
        this.links.add(link);
    }

    /**
     * @return the links
     */
    public List<MenuLink> getLinks() {
        return this.links;
    }

    /**
     * @return the subMenuItems
     */
    public Collection<MenuItem> getChildren() {
        return this.subMenuItems.values();
    }

    /**
     * @return o label desse menu
     */
    public String getLabel() {
        return this.label;
    }

    /**
     * Devolve um menu que é filho deste menu de acordo com o path passado.
     * 
     * @param menuPath uma sequencia de labels, separadas por ':', que indica o caminho na hierarquia do menu.
     * @return Um submenu na hierarquia desse menu, ou ele mesmo caso o caminho seja vazio.
     */
    public MenuItem getMenu(String menuPath) {
        if (this.label.equals(menuPath)) {
            return this;
        }
        int index = menuPath.indexOf(SEPARATOR);
        String l = index >= 0 ? menuPath.substring(0, index) : menuPath;
        MenuItem subMenu = this.subMenuItems.get(l);
        return subMenu != null ? subMenu.getMenu(l.substring(index + SEPARATOR.length())) : null;
    }

    /**
     * @return the path
     */
    public String getPath() {
        return this.path.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "Menu Item: " + this.label;
    }

}
